﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace ReplaceFileVersion
{
    public class ReplaceJsComma
    {
        protected readonly List<string> Files = new List<string>();
        protected Regex ScriptRegex = new Regex(@"<script\b([^>]*?)>([\w\W]*?)</script>", RegexOptions.IgnoreCase);
        protected string LogDir { get; private set; }

        private ReplaceJsComma()
        {
            var logDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log");
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }
            LogDir = logDir;
        }
        public ReplaceJsComma(string filePath, string searchFilePattern)
            : this()
        {
            if (File.Exists(filePath))
            {
                Files.Add(filePath);
            }
            else if (Directory.Exists(filePath))
            {
                if (string.IsNullOrWhiteSpace(searchFilePattern))
                {
                    var fileArr = Directory.GetFiles(filePath, "*.*", SearchOption.AllDirectories);
                    Files.AddRange(fileArr);
                }
                else
                {
                    foreach (var s in searchFilePattern.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        var fileArr = Directory.GetFiles(filePath, s, SearchOption.AllDirectories);
                        Files.AddRange(fileArr);
                    }
                    Files = Files.Distinct().ToList();
                }
            }
            else
            {
                MessageBox.Show(string.Format("文件、目录[{0}]不存在！", filePath));
            }
        }

        public IDictionary<string, IList<string>> Replace()
        {
            var dict = new ConcurrentDictionary<string, IList<string>>();
            // var list = new ConcurrentQueue<string>();
            //  var regex = new Regex(ReplacePattern, RegexOptions.IgnoreCase);
            var jsType = new Regex(@"type=['""](text|application)/javascript['""]", RegexOptions.IgnoreCase);
            var commaRegex = new Regex(@"[\w\W]{0,50},\s*[\)\]\}][\w\W]{0,50}");
            Files.AsParallel().ForAll(path =>
            {
                var text = File.ReadAllText(path);
                var list = new List<string>();
                if (Path.GetExtension(path).Equals(".js", StringComparison.OrdinalIgnoreCase))
                {
                    list.Add(text);
                }
                else
                {
                    var matches = ScriptRegex.Matches(text);
                    foreach (Match match in matches)
                    {
                        if (match.Success)
                        {
                            var scriptAttr = match.Groups[1].Value;
                            if (!string.IsNullOrWhiteSpace(scriptAttr))
                            {
                                if (scriptAttr.IndexOf(" src=", StringComparison.OrdinalIgnoreCase) != -1)
                                {
                                    continue;
                                }
                                if (scriptAttr.IndexOf(" type=", StringComparison.OrdinalIgnoreCase) != -1
                                    && !jsType.IsMatch(scriptAttr))
                                {
                                    continue;
                                }
                            }
                            var scriptContent = match.Groups[2].Value;
                            //list.Add(match.Value);
                            list.Add(scriptContent);
                        }
                    }
                }
                var list2=new List<string>();
                foreach (var item in list)
                {
                    var matches = commaRegex.Matches(item);
                    foreach (Match match in matches)
                    {
                        if (match.Success)
                        {
                            list2.Add(match.Value);
                        }
                    }
                }
                if (list2.Any())
                {
                    dict.TryAdd(path, list2);
                }
            });
            return dict;
        }

        public string WriteLog(IDictionary<string, IList<string>> list)
        {
            var path = Path.Combine(LogDir, "ReplaceJsComma_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".log");
            var sb = new StringBuilder();
            foreach (var item in list)
            {
                sb.AppendLine(item.Key);
                foreach (var line in item.Value)
                {
                    sb.Append("     ").AppendLine(line);
                }
                sb.AppendLine().AppendLine();
            }
            File.WriteAllText(path, sb.ToString());
            return path;
        }

    }
}
